﻿using Furion;
using Furion.DatabaseAccessor;
using LimaLims.Core.Const;
using LimaLims.Core.Entity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace LimaLims.EntityFramework.Core.DbContext
{
    [AppDbContext("SqlServerConnectionString")]
    public class MultiTenantDbContext : AppDbContext<MultiTenantDbContext, MultiTenantDbContextLocator>, IMultiTenantOnTable, IModelBuilderFilter
    {
        public MultiTenantDbContext(DbContextOptions<MultiTenantDbContext> options) : base(options)
        {
            EnabledEntityStateTracked = false;
            // 忽略空值更新
            InsertOrUpdateIgnoreNullValues = true;
        }

        public object GetTenantId()
        {
            if (App.User == null) return 142307070918780;
            return Convert.ToInt64(App.User.FindFirst(ClaimConst.TENANT_ID)?.Value);
        }

        public void OnCreating(ModelBuilder modelBuilder, EntityTypeBuilder entityBuilder, Microsoft.EntityFrameworkCore.DbContext dbContext, Type dbContextLocator)
        {
            entityBuilder.HasQueryFilter(BuildTenantQueryFilter(entityBuilder, dbContext));
        }

        protected override void SavingChangesEvent(DbContextEventData eventData, InterceptionResult<int> result)
        {
            // 获取所有已更改的实体
            var entities = eventData.Context.ChangeTracker.Entries()
                                    .Where(u => u.State == EntityState.Modified || u.State == EntityState.Deleted || u.State == EntityState.Added)
                                    .ToList();

            // 当前操作用户信息
            var userId = App.User.FindFirst(ClaimConst.CLAINM_USERID)?.Value;
            var userName = App.User.FindFirst(ClaimConst.CLAINM_NAME)?.Value;

            foreach (var entity in entities)
            {
                if (entity.Entity.GetType().IsSubclassOf(typeof(DEntityBase<Guid, MultiTenantDbContextLocator>)))
                {
                    var obj = entity.Entity as DEntityBase<Guid, MultiTenantDbContextLocator>;
                    if (entity.State == EntityState.Added)
                    {
                        obj.Id = Guid.NewGuid();
                        obj.CreatedTime = DateTime.Now;
                        if (!string.IsNullOrEmpty(userId))
                        {
                            obj.CreatedUserId = long.Parse(userId);
                            obj.CreatedUserName = userName;
                        }
                    }
                    else if (entity.State == EntityState.Modified)
                    {
                        obj.UpdatedTime = DateTime.Now;
                        obj.UpdatedUserId = long.Parse(userId);
                        obj.UpdatedUserName = userName;
                    }
                }
            }
        }
    }
}
